package com.yokead.controller.api;

import cn.jiangzeyin.DateFormat;
import cn.jiangzeyin.DateUtil;
import cn.jiangzeyin.StringUtil;
import cn.jiangzeyin.common.JsonMessage;
import com.alibaba.druid.util.JdbcUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yokead.common.Config;
import com.yokead.common.base.AbstractBaseControl;
import com.yokead.common.interceptor.NotLogin;
import com.yokead.database.DatabaseContextHolder;
import com.yokead.service.BaseService;
import com.yokead.service.order.ProductService;
import com.yokead.system.log.LogType;
import com.yokead.system.log.SystemLog;
import com.yokead.util.JsonUtil;
import org.springframework.context.annotation.Scope;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.WebApplicationContext;

import javax.sql.DataSource;
import java.io.File;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * Created by jiangzeyin on 2017/5/16.
 */
@Controller
@Scope(WebApplicationContext.SCOPE_SESSION)
public class ApiControl extends AbstractBaseControl {

    /**
     * 下单接口
     *
     * @param customer 客户名
     * @param gid      广告位
     * @param product  产品名
     * @param source   来源
     * @return json
     */
    @RequestMapping(value = "api/order.json", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    @NotLogin
    public String data(String customer, String gid, String product, String source, String gzid) {
        customer = convertFilePath(customer);
        product = convertFilePath(product);
        File customerFile = new File(Config.Order.getOrderConfigPath(), customer);
        if (!customerFile.exists() || !customerFile.isDirectory())
            return JsonMessage.getString(100, "提交失败，请正确使用订单系统");
        File fileProduct = new File(customerFile, product);
        if (!fileProduct.exists() || !fileProduct.isDirectory())
            return JsonMessage.getString(101, "提交失败，请正确使用订单系统");
        File productConf = new File(customerFile, "product.conf");
        if (!productConf.exists() || productConf.isDirectory())
            return JsonMessage.getString(102, "提交失败，订单系统异常");
        JSONArray jsonArray;
        try {
            jsonArray = (JSONArray) JsonUtil.readJson(productConf.getPath());
        } catch (Exception e) {
            SystemLog.LOG(LogType.CONTROL_ERROR).error("订单失败", e);
            return JsonMessage.getString(103, "提交失败，订单系统异常!");
        }
        if (jsonArray == null)
            return JsonMessage.getString(104, "提交失败，订单系统异常!");
        String tableName = null;
        String orderType = null;
        for (int i = jsonArray.size() - 1; i >= 0; i--) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            String name = jsonObject.getString("name");
            if (product.equals(name)) {
                tableName = jsonObject.getString("tableName");
                orderType = jsonObject.getString("orderType");
                break;
            }
        }
        if (tableName == null || orderType == null)
            return JsonMessage.getString(105, "提交失败，订单系统异常!");
        File orderTypeFile = BaseService.getOrderTypeConfigFile();//getOrderTypeFile();
        JSONArray orderTypeArray;
        try {
            orderTypeArray = (JSONArray) JsonUtil.readJson(orderTypeFile.getPath());
        } catch (Exception e) {
            SystemLog.LOG(LogType.CONTROL_ERROR).error("订单失败", e);
            return JsonMessage.getString(107, "提交失败，订单系统异常!");
        }
        if (orderTypeArray == null)
            return JsonMessage.getString(108, "提交失败，订单系统异常!");
        JSONArray tableInfo = null;
        for (int i = orderTypeArray.size() - 1; i >= 0; i--) {
            JSONObject jsonObject = orderTypeArray.getJSONObject(i);
            String name = jsonObject.getString("name");
            if (orderType.equals(name)) {
                tableInfo = jsonObject.getJSONArray("table");
                break;
            }
        }
        if (tableInfo == null || tableInfo.size() < 1)
            return JsonMessage.getString(109, "提交失败，订单系统异常!");
        StringBuffer columns = new StringBuffer();
        List<Object> parameters = new LinkedList<>();
        JSONObject parNameOfColumns = new JSONObject();

        for (int i = tableInfo.size() - 1; i >= 0; i--) {
            JSONObject jsonObject = tableInfo.getJSONObject(i);
            if (columns.length() >= 1)
                columns.append(",");
            String name = jsonObject.getString("name");
            columns.append(name);
            String parName = jsonObject.getString("parName");
            String value = StringUtil.filterHTML(getParameter(parName, ""));
            parNameOfColumns.put(name, parName);
            parameters.add(value);
        }
        columns.append(",ip");
        parameters.add(getIp());
        columns.append(",source");
        parameters.add(source);
        columns.append(",gid");
        // 处理广告位
        if (StringUtil.isEmpty(gid))
            gid = gzid;
        parameters.add(gid);
        columns.append(",uga");
        String uag = getUserAgent();

        int isDelete = 0;

        DataSource dataSource = DatabaseContextHolder.getDataSource();
        String limitTip = "下单成功:-100";
        Boolean maskTip = true;
        //  判断下单限制
        try {
            JSONArray config = ProductService.getProductLimitDuplicateConfig(customer, product);
            if (config != null) {
                int cTime = DateUtil.getCurrentShortTimeMillis();
                Boolean dataIntercept = true;
                int len = config.size();
                for (int i = len - 1; i >= 0; i--) {
                    JSONObject jsonObject = config.getJSONObject(i);
                    String columnName = jsonObject.getString("name");
                    if (columnName == null) {
                        // 最后一项是数据配置
                        if (i == len - 1) {
                            dataIntercept = jsonObject.getBoolean("dataIntercept");
                            if (dataIntercept == null)
                                dataIntercept = true;
                            maskTip = jsonObject.getBoolean("maskTip");
                            if (maskTip == null)
                                maskTip = true;
                        }
                        continue;
                    }
                    int limit = jsonObject.getIntValue("limit");
                    if (limit <= 0)
                        continue;
                    String val;
                    if ("ip".equalsIgnoreCase(columnName)) {
                        val = getIp();
                    } else if ("gid".equalsIgnoreCase(columnName)) {
                        val = gid;
                    } else {
                        String parName = parNameOfColumns.getString(columnName);
                        if (StringUtil.isEmpty(parName))
                            continue;
                        val = StringUtil.filterHTML(getParameter(parName, ""));
                    }
                    if (StringUtil.isEmpty(val))
                        continue;
                    String sql = String.format("select count(1) as cut  from %s where %s=? and createTime>=%s", tableName, columnName, cTime - limit);
                    SystemLog.LOG().info(sql);
                    List<Map<String, Object>> mapList = JdbcUtils.executeQuery(dataSource, sql, val);
                    if (mapList.size() <= 0)
                        continue;
                    Map<String, Object> map = mapList.get(0);
                    int count = StringUtil.parseInt(map.get("cut"));
                    if (count >= 1) {
                        limitTip = maskTip ? "下单成功:-100" : String.format("下单过于频繁，请%s后再下单", DateFormat.getTimeMessage(limit));
                        // 如果是超过限制默认已删除
                        if (!dataIntercept) {
                            return JsonMessage.getString(403, limitTip);
                        }
                        isDelete = 1;
                        // 限制的原因
                        uag += "(" + columnName + ":" + limit + ":" + count + ")";
                        break;
                    }
                }
            }
        } catch (Exception e) {
            SystemLog.LOG(LogType.CONTROL_ERROR).error("下单限制失败", e);
        }
        // 记录uag 和失败原因
        parameters.add(uag);

        String sql = String.format("insert into %s(%s,createTime,isDelete) values(%s,UNIX_TIMESTAMP(NOW()),%s)", tableName, columns, get(parameters.size()), isDelete);
        SystemLog.LOG().info(sql);
        try {
            JdbcUtils.execute(dataSource, sql, parameters);
        } catch (Exception e) {
            SystemLog.LOG(LogType.CONTROL_ERROR).error("下单失败", e);
            return JsonMessage.getString(100, "下单失败，请稍等重试");
        }
        if (isDelete == 0)
            return JsonMessage.getString(200, "下单成功");
        return JsonMessage.getString(maskTip ? 200 : 403, limitTip);
    }

    /**
     * 跨域订单信息
     *
     * @param customer 客户名
     * @param gid      gid
     * @param product  产品
     * @param source   来源
     * @param gzid     gzid
     * @return json
     */
    @RequestMapping(value = "api2/order.json", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    @NotLogin
    @CrossOrigin
    public String api2(String customer, String gid, String product, String source, String gzid) {
        return data(customer, gid, product, source, gzid);
    }

    private String get(int count) {
        StringBuilder sql = new StringBuilder();
        for (int i = 0; i < count; i++) {
            if (i > 0)
                sql.append(",");
            sql.append("?");
        }
        return sql.toString();
    }

//    private String getConfPath() {
//        return String.format("%s/%s", SystemBean.getInstance().getEnvironment().getProperty("order.conf"), "conf/customer");
//    }

//    private File getOrderTypeFile() {
//        // return String.format("%s/%s", SystemBean.getInstance().getEnvironment().getProperty("order.conf"), "/conf/ordertype/type.conf");
//        return BaseService.getOrderTypeConfigFile();
//    }
}
